/**
 * 在给定的网格中，每个单元格可以有以下三个值之一：

值 0 代表空单元格；
值 1 代表新鲜橘子；
值 2 代表腐烂的橘子。
每分钟，任何与腐烂的橘子（在 4 个正方向上）相邻的新鲜橘子都会腐烂。

返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能，返回 -1。

示例 1：
输入：[[2,1,1],[1,1,0],[0,1,1]]
输出：4
示例 2：

输入：[[2,1,1],[0,1,1],[1,0,1]]
输出：-1
解释：左下角的橘子（第 2 行， 第 0 列）永远不会腐烂，因为腐烂只会发生在 4 个正向上。
示例 3：

输入：[[0,2]]
输出：0
解释：因为 0 分钟时已经没有新鲜橘子了，所以答案就是 0 。
 
提示：
1 <= grid.length <= 10
1 <= grid[0].length <= 10
grid[i][j] 仅为 0、1 或 2
 */

(function () {
    /**
     * @description 本题类似于542. 01矩阵，区别在于需要同一时间处理所有腐烂橘子周围的橘子，即 
     *      const length = queue.length;
            for (let i = 0; i < length; i++) {...}
            处理完了时间再+1
     * @param grid 
     * @returns 
     */
    function orangesRotting(grid: number[][]): number {
        const checkRow = [1, -1, 0, 0];
        const checkCol = [0, 0, 1, -1];
        const queue: number[][] = [];
        for (let i = 0; i < grid.length; i++) {
            for (let j = 0; j < grid[0].length; j++) {
                if (grid[i][j] === 2) {
                    queue.push([i, j]);
                }
            }
        }
        let minute = 0;
        while (queue.length > 0) {
            const length = queue.length;
            for (let i = 0; i < length; i++) {
                const cur = queue.shift();
                if (cur) {
                    const [row, col] = cur;
                    for (let j = 0; j < checkRow.length; j++) {
                        let n_row = row + checkRow[j];
                        let n_col = col + checkCol[j];
                        if (
                            n_row >= 0 &&
                            n_row < grid.length &&
                            n_col >= 0 &&
                            n_col < grid[0].length &&
                            grid[n_row][n_col] === 1
                        ) {
                            grid[n_row][n_col] = 2;
                            queue.push([n_row, n_col]);
                        }
                    }
                }
            }

            if (queue.length > 0) {
                minute++;
            }
        }

        for (let i = 0; i < grid.length; i++) {
            for (let j = 0; j < grid[0].length; j++) {
                if (grid[i][j] === 1) {
                    return -1;
                }
            }
        }

        return minute;
    }
})();
